#include "ARI.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "analex.h"

static unsigned int tabulacao = 0;

void ImprimeARI::imprimeTabulacao(){
     for(int unsigned n=0; n <= tabulacao; n++) {
         fprintf(stdout, "   ");
     }
}

ImprimeARI::ImprimeARI() {
    //fprintf(stdout, "\n\n*****ARVORE DE REPRESENTACAO INTERMEDIARIA*****\n\n");
}

/**FrameMIPS**/
void ImprimeARI::visitar(FrameMIPS *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "FrameMips\n");
	}
	if(v->rotulo != NULL) v->rotulo->aceitar(this);
	if(v->dadosLocais != NULL) v->dadosLocais->aceitar(this);
	if(v->valorRetorno != NULL) v->valorRetorno->aceitar(this);
	tabulacao--;
}

/**FragmentList**/
void ImprimeARI::visitar(FragmentList *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "FragmentList\n");
	}
	if(v->fragmento != NULL) v->fragmento->aceitar(this);
	if(v->fragmentList != NULL) v->fragmentList->aceitar(this);
	tabulacao--;
}

/**Procedure**/
void ImprimeARI::visitar(Procedure *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "Procedure\n");
	}
	if(v->frame != NULL) v->frame->aceitar(this);
	if(v->corpo != NULL) v->corpo->aceitar(this);
	tabulacao--;
}

/**Literal**/
void ImprimeARI::visitar(Literal *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "Literal\n");
	}
	if(v->l != NULL) v->l->aceitar(this);
	if(v->aLiteral != NULL) {
	    imprimeTabulacao();
        fprintf(stdout, " nome: %s\n", v->aLiteral);
	}
	tabulacao--;
}

/**Inteiro**/
void ImprimeARI::visitar(Inteiro *v) {
    tabulacao++;
	if(v != NULL) {
	    imprimeTabulacao();
        fprintf(stdout, "Inteiro\n");
        if(v->l) v->l->aceitar(this);
        if(v->nElementos != 0) {
            imprimeTabulacao();
            fprintf(stdout, " nElementos: %d\n", v->nElementos);
        }
	}
	tabulacao--;
}

/**Real**/
void ImprimeARI::visitar(Real *v) {
    tabulacao++;
	if(v != NULL) {
	    imprimeTabulacao();
        fprintf(stdout, "Real\n");
	}
	if(v->l != NULL) v->l->aceitar(this);
	if(v->nElementos != 0) {
        imprimeTabulacao();
        fprintf(stdout, " nElementos: %d\n", v->nElementos);
	}
	tabulacao--;
}

/**Logico**/
void ImprimeARI::visitar(Logico *v) {
    tabulacao++;
	if(v != NULL) {
	    imprimeTabulacao();
        fprintf(stdout, "Logico\n");
	}
	if(v->l != NULL) v->l->aceitar(this);
    if(v->nElementos != 0) {
        imprimeTabulacao();
	    fprintf(stdout, " nElementos: %d\n", v->nElementos);
	}
	tabulacao--;
}

/**Registro**/
void ImprimeARI::visitar(Registro *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "Registro\n");
	}
	if(v->l != NULL) v->l->aceitar(this);
    if(v->nBytes != 0) {
        imprimeTabulacao();
        fprintf(stdout, " nBytes: %d\n", v->nBytes);
    }
    if(v->nElementos != 0) {
        imprimeTabulacao();
        fprintf(stdout, " nElementos: %d\n", v->nElementos);
	}
	tabulacao--;
}

/**Lista Acesso**/
void ImprimeARI::visitar(ListaAcesso *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "Lista de Acesso\n");
	}
	if(v->local != NULL) v->local->aceitar(this);
	if(v->proximo != NULL) v->proximo->aceitar(this);

	tabulacao--;
}

/**inFrame**/
void ImprimeARI::visitar(inFrame *v) {
    tabulacao++;
	if(v != NULL) {
	    imprimeTabulacao();
        fprintf(stdout, "InFrame\n");
	}
	if(v->offset != 0) {
	    imprimeTabulacao();
	    fprintf(stdout, " offset: %d\n", v->offset);
	}
	tabulacao--;
}

/**Temp**/
void ImprimeARI::visitar(Temp *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "Temp\n");
	}
	if(v->nome != NULL) {
	    imprimeTabulacao();
	    fprintf(stdout, " nome: %s\n", v->nome);
	}
	tabulacao--;
}

/**Label**/
void ImprimeARI::visitar(Label *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "Label\n");
	}
	if(v->nome != NULL) {
	    imprimeTabulacao();
	    fprintf(stdout, " nome: %s\n", v->nome);
	}
	tabulacao--;
}

/**LabelList**/
void ImprimeARI::visitar(LabelList *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "LabelList\n");
	}
	if(v->label != NULL) v->label->aceitar(this);
	if(v->proximo != NULL) v->proximo->aceitar(this);
	tabulacao--;
}

/**StmList**/
void ImprimeARI::visitar(StmList *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "StmList\n");
	}
	if(v->prim != NULL) v->prim->aceitar(this);
	if(v->prox != NULL) v->prox->aceitar(this);
	tabulacao--;
}

/**ExpList**/
void ImprimeARI::visitar(ExpList *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "ExpList\n");
	}
	if(v->prim != NULL) v->prim->aceitar(this);
	if(v->prox != NULL) v->prox->aceitar(this);
	tabulacao--;
}

/**CONST**/
void ImprimeARI::visitar(CONST *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "CONST\n");
	}
	if(v->valor != 0) {
        imprimeTabulacao();
	    fprintf(stdout, " valor: %d\n", v->valor);
	}
	tabulacao--;
}

/**CONSTF**/
void ImprimeARI::visitar(CONSTF *v) {
    tabulacao++;
	if(v != NULL) {
	    imprimeTabulacao();
        fprintf(stdout, "CONSTF\n");
	}
	if(v->valor != 0) {
        imprimeTabulacao();
        fprintf(stdout, " valor: %f\n", v->valor);
	}
	tabulacao--;
}

/**NAME**/
void ImprimeARI::visitar(NAME *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "NAME\n");
	}
	if(v->rotulo != NULL) v->rotulo->aceitar(this);
	tabulacao--;
}

/**TEMP**/
void ImprimeARI::visitar(TEMP *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "TEMP\n");
	}
	if(v->temporario != NULL) v->temporario->aceitar(this);
	tabulacao--;
}

/**BINOP**/
void ImprimeARI::visitar(BINOP *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "BINOP\n");
	}
	if(v->operador != 0) {
        imprimeTabulacao();
	    fprintf(stdout, " operador: %s\n", retornaNomeToken(v->operador));
	}
	if(v->expressao1 != NULL) v->expressao1->aceitar(this);
	if(v->expressao2 != NULL) v->expressao2->aceitar(this);
	tabulacao--;
}

/**MEM**/
void ImprimeARI::visitar(MEM *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "MEM\n");
	}
	if(v->expressao != NULL) v->expressao->aceitar(this);
	tabulacao--;
}

/**CALL**/
void ImprimeARI::visitar(CALL *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "CALL\n");
	}
	if(v->funcao != NULL) v->funcao->aceitar(this);
	if(v->argumentos != NULL) v->argumentos->aceitar(this);
	tabulacao--;
}

/**ESEQ**/
void ImprimeARI::visitar(ESEQ *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "ESEQ\n");
	}
	if(v->sentenca != NULL) v->sentenca->aceitar(this);
	if(v->expressao != NULL) v->expressao->aceitar(this);
	tabulacao--;
}

/**MOVE**/
void ImprimeARI::visitar(MOVE *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "MOVE\n");
	}
	if(v->destino != NULL) v->destino->aceitar(this);
	if(v->origem != NULL) v->origem->aceitar(this);
	tabulacao--;
}

/**EXP**/
void ImprimeARI::visitar(EXP *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "EXP\n");
	}
	if(v->expressao != NULL) v->expressao->aceitar(this);
	tabulacao--;
}

/**JUMP**/
void ImprimeARI::visitar(JUMP *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "JUMP\n");
	}
	if(v->l != NULL) v->l->aceitar(this);
	tabulacao--;
}

/**CJUMP**/
void ImprimeARI::visitar(CJUMP *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "CJUMP\n");
	}
	if(v->relop != 0) {
        imprimeTabulacao();
	    fprintf(stdout, " operador: %s\n", retornaNomeToken(v->relop));
	}
	if(v->esq != NULL) v->esq->aceitar(this);
	if(v->dir != NULL) v->dir->aceitar(this);
	if(v->casoVerdadeiro != NULL) v->casoVerdadeiro->aceitar(this);
	if(v->casoFalso != NULL) v->casoFalso->aceitar(this);
	tabulacao--;
}

/**SEQ**/
void ImprimeARI::visitar(SEQ *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "SEQ\n");
	}
	if(v->esq != NULL) v->esq->aceitar(this);
	if(v->dir != NULL) v->dir->aceitar(this);
	tabulacao--;
}

/**LABEL**/
void ImprimeARI::visitar(LABEL *v) {
    tabulacao++;
	if(v != NULL) {
        imprimeTabulacao();
        fprintf(stdout, "LABEL\n");
	}
	if(v->l != NULL) v->l->aceitar(this);
	tabulacao--;
}
